package com.google.code.p.narcissus.core;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.rmi.Naming;
import java.rmi.RemoteException;

import org.apache.log4j.Logger;

import com.google.code.p.narcissus.core.remote.IRemoteRobot;
import com.google.code.p.narcissus.core.remote.NarcissusServer;


public class ScreenCaptureRobot {

	private static final Logger logger = Logger.getLogger(ScreenCaptureRobot.class.getName());

	private Robot robot;

	private IRemoteRobot remoteRobot;

	public ScreenCaptureRobot() throws NarcissusException {
		try {
			if ("local".equals(getToLowerCaseProperty(NarcissusServer.NARCISSUS_SERVER_TYPE_KEY, "local"))) {
				robot = new Robot();
			} else {
				// Initialize the remoteRobot using RMI
				remoteRobot = (IRemoteRobot) Naming.lookup("//" + getToLowerCaseProperty(NarcissusServer.NARCISSUS_SERVER_HOST_KEY, "127.0.0.1") + ":"
						+ getToLowerCaseProperty(NarcissusServer.NARCISSUS_SERVER_PORT_KEY, "2004") + "/"
						+ System.getProperty(NarcissusServer.NARCISSUS_SERVICE_NAME_KEY, "ScreenShooter"));
			}
		} catch (Exception anyEx) {
			logger.error("Impossible to instanciate the robot to take screenshots!", anyEx);
			throw new NarcissusException("Impossible to instanciate the robot to take screenshots!", anyEx);
		}
	}

	private String getToLowerCaseProperty(String propertyName, String defaultValue) {
		return System.getProperty(propertyName, defaultValue).toLowerCase();
	}

	public BufferedImage createScreenCapture(Rectangle snapRect) throws NarcissusException {
		if (robot != null) {
			return robot.createScreenCapture(snapRect);
		} else {
			try {
				return remoteRobot.createScreenCapture(snapRect).getBufferedImage();
			} catch (RemoteException e) {
				throw new NarcissusException(e);
			} catch (IOException e) {
				throw new NarcissusException(e);
			}
		}
	}

	public void mouseMove(int x, int y) throws NarcissusException {
		if (robot != null) {
			robot.mouseMove(x, y);
		} else {
			try {
				remoteRobot.mouseMove(x, y);
			} catch (RemoteException e) {
				throw new NarcissusException(e);
			}
		}
	}

	public Dimension getScreenSize() throws NarcissusException {
		if (robot != null) {
			return Toolkit.getDefaultToolkit().getScreenSize();
		} else {
			try {
				return remoteRobot.getScreenSize();
			} catch (RemoteException e) {
				throw new NarcissusException(e);
			}
		}
	}

}